﻿using AutoCSer.Net;
using System;
using System.Runtime.CompilerServices;

namespace AutoCSer.CommandService.StreamPersistenceMemoryDatabase
{
    /// <summary>
    /// Server node method information
    /// 服务端节点方法信息
    /// </summary>
    public abstract class Method
    {
        /// <summary>
        /// Method Number
        /// 方法编号
        /// </summary>
        internal readonly int Index;
        /// <summary>
        /// The method number that checks the input parameter before the persistence operation
        /// 持久化操作之前检查输入参数的方法编号
        /// </summary>
        internal readonly int BeforePersistenceMethodIndex;
        /// <summary>
        /// Method call type
        /// 方法调用类型
        /// </summary>
        internal readonly CallTypeEnum CallType;
        /// <summary>
        /// Server-side node method flags
        /// 服务端节点方法标记
        /// </summary>
        internal readonly MethodFlagsEnum Flags;
        /// <summary>
        /// Server-side node method flags
        /// 服务端节点方法标记
        /// </summary>
        internal MethodFlagsEnum TwoStageFlags { get { return ServerNodeMethod.GetTwoStageFlags(Flags); } }
        /// <summary>
        /// Whether to persist (persistence is required if write operations are involved)
        /// 是否持久化（涉及写入操作则需要持久化）
        /// </summary>
        internal readonly bool IsPersistence;
        /// <summary>
        /// Whether the client is allowed to call it or not, otherwise it is a server memory call method
        /// 是否允许客户端调用，否则为服务端内存调用方法
        /// </summary>
        internal readonly bool IsClientCall;
        ///// <summary>
        ///// 是否简单序列化输出数据
        ///// </summary>
        //internal bool IsSimpleSerializeParamter
        //{
        //    get { return (Flags & MethodFlagsEnum.IsSimpleSerializeParamter) != 0; }
        //}
        /// <summary>
        /// Whether to simply deserialize the input data
        /// 是否简单反序列化输入数据
        /// </summary>
        internal bool IsSimpleDeserializeParamter
        {
            get { return (Flags & MethodFlagsEnum.IsSimpleDeserializeParamter) != 0; }
        }
        /// <summary>
        /// Whether to ignore the persistence callback exception, the node method must ensure that the memory data state is restored when an exception occurs. It must be concerned about the memory shortage exception generated by new, and all new operations should be completed before modifying the data
        /// 是否忽略持久化回调异常，节点方法必须保证异常时还原恢复内存数据状态，必须关心 new 产生的内存不足异常，在修改数据以前应该将完成所有 new 操作
        /// </summary>
        internal bool IsIgnorePersistenceCallbackException
        {
            get { return (Flags & MethodFlagsEnum.IsIgnorePersistenceCallbackException) != 0; }
        }
        ///// <summary>
        ///// 是否快照调用方法，该方法必须只有 1 个参数且类型匹配快照数据
        ///// </summary>
        //internal bool IsSnapshotMethod
        //{
        //    get { return (flags & MethodFlags.IsSnapshotMethod) != 0; }
        //}
        /// <summary>
        /// Server node method information
        /// 服务端节点方法信息
        /// </summary>
        /// <param name="index">Method Number
        /// 方法编号</param>
        /// <param name="beforePersistenceMethodIndex">The method number that checks the input parameter before the persistence operation
        /// 持久化操作之前检查输入参数的方法编号</param>
        /// <param name="callType">Method call type
        /// 方法调用类型</param>
        /// <param name="flags">Server-side node method flags
        /// 服务端节点方法标记</param>
        internal Method(int index, int beforePersistenceMethodIndex, CallTypeEnum callType, MethodFlagsEnum flags)
        {
            Index = index;
            BeforePersistenceMethodIndex = beforePersistenceMethodIndex;
            CallType = callType;
            this.Flags = flags;
            IsPersistence = (flags & MethodFlagsEnum.IsPersistence) != 0;
            IsClientCall = (flags & MethodFlagsEnum.IsClientCall) != 0;
        }
        /// <summary>
        /// Create the calling method and parameter information
        /// 创建调用方法与参数信息
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
#if NetStandard21
        internal virtual InputMethodParameter? CreateInputParameter(ServerNode node)
#else
        internal virtual InputMethodParameter CreateInputParameter(ServerNode node)
#endif
        {
            return null;
        }
    }
}
